define(function(require, exports, module) {
	var $$ = require('common/lang');

	exports.parser = parser;
	exports.render = render;

	function parser(dom, arr, cols, data){
		while(dom){
			if(dom.nodeType == 1 || dom.nodeType == 3){
				var _tplNode = new tplNode(dom, data, cols); 
				if(dom.children && dom.children.length){
					arguments.callee(dom.childNodes[0], _tplNode.children, _tplNode.cols + 1, _tplNode.data);
				}

				arr.push(_tplNode);
			}
			dom = dom.nextSibling;
		}
	}
	// alert(9);
	function tplNode(dom, data, cols){
		var node = {
			dom : dom,
			isSubTpl	: dom.tagName == 'TPL',
			isIF		: dom.tagName == 'IF',
			isTextNode  : dom.nodeType == 3,
			children	: [],
			tplBody		: dom.nodeType == 3 ? dom.nodeValue : dom.innerHTML,
			cols 		: cols,
			parentData	: data
		};

		if(dom.nodeType == 1){ // Element Type
			var _arr = dom.outerHTML.match(this.getTagNameAndFullAttrib);
			node.holder = _arr[0] +  '\n{0}\n{1}</' + _arr[1] + '>\n';
		}else if(dom.nodeType == 3){
			node.holder = dom.nodeValue.trim();
			if(node.holder){
				node.holder += '\n';
			}else{
				node.holder = '\n' + node.holder;
			}
		}

		if(node.isSubTpl){
			var dataScope, scope = _arr[0].match(this.getForStatement);

			scope = scope[1], dataScope = data[scope];

			if(!scope || !dataScope){
				console.warn('【tpl】模板编写有错？没有期望的数据字段:scope = ' + scope);
				node.data = {};
			}else{
				node.data = dataScope;
			}
		}else{
			// if(!dom.children.length)debugger;
			node.data = data;
		}

		if(node.isSubTpl || node.isIF){
			node.holder = '\n{0}\n{1}'; // <tpl><if>无须 <tpl></tpl><if></if>
			node.cols	= node.cols - 1;
		}

		for(var i in node){
			this[i] = node[i];
		}
	}
	tplNode.prototype = {
		/**
		 * 获取标签的开始部分
		 * @type {RegExp}
		 */
		getTagNameAndFullAttrib : /<(\w+)[^>]*>/,

		/**
		 * 获取 <tpl for="XXX"> 中的 XXX 部分
		 * @type {RegExp}
		 */
		getForStatement : /for="(\w+)"/i
	};

	/**
	 * 编译模板。为静态数据生成一个函数
	 * @param  {String} tpl [description]
	 * @return {Function}     [description]
	 */
	function complieTpl(tpl){
		var getHold = /\{([^\}]+)\}/ig; // 获取 洞洞
		
		if (getHold.test(tpl) || !tpl){
			var fnBody = tpl.replace(getHold, '" + $1 +"');
			fnBody = fnBody.trim();
			fnBody = 'with(data){\
				return "' + fnBody + '"; \
			};';

			return new Function('data', 'index', 'length', 'parentData', fnBody);
		}else{
			console.log('【tpl】模板不需要替换？~~没发现有插值符号' + tpl);
			return function(){ return '';}
		}
	}

	/**
	 * 替换函数
	 * @param  {Object} node [description]
	 * @return {String}      [description]
	 */
	function replace(node){
		var frag = '', data = node.data, tabIndent = node.cols + 1, 
			tabIndent = new Array(tabIndent), tabIndent = tabIndent.join('     ');

		if(data instanceof Array){
			var complieFn = complieTpl(node.tplBody);
			var fragHtml;

			for(var i = 0, j = data.length; i < j; i++){
				fragHtml  = '';
				fragHtml += tabIndent;
				fragHtml += complieFn(data[i], i, j, node.parentData);
				fragHtml += (i == j - 1) ? '' : '\n'; // 最后一个不加换行

				frag += fragHtml;
			}
		}else{
			frag = tabIndent + node.tplBody.format(data);
		}

		// console.log('innerHTML' + node.tplBody);

		return frag;
	}

	/**
	 * 输入语法树，通过递归得到已渲染的 HTML。
	 * @param  {Array} arr [description]
	 * @return {String}     [description]
	 */
	function render(arr){
		var str = '';
		for(var node, i = 0, j = arr.length; i < j; i++){
			node = arr[i];
			// console.log('tpl'+node.tpl);
			if(node.isIF && !eval(node.dom.getAttribute('test'))){
				continue;
			}

			var frag = '';
			if(node.children && node.children.length){
				frag = arguments.callee(node.children) ;
			}else{
				// 执行单纯的替换工作，没有子元素、后裔了
				frag = replace(node);
			}

			var tabs = node.cols;
			tabs = new Array(tabs);
			tabs = tabs.join('      ');
			str += tabs;
			str += node.holder.format(frag, tabs);
		}

		return str;
	}
});